package com.asset.service.impl;

import com.asset.mapper.AssetMapper;
import com.asset.mapper.CompanyMapper;
import com.asset.mapper.DepreciationMapper;
import com.asset.model.entity.Asset;
import com.asset.model.entity.DepDetail;
import com.asset.model.entity.DepreciationDetail;
import com.asset.model.entity.DepreciationRecord;
import com.asset.service.DepreciationService;
import com.asset.utils.DepreciationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DepreciationServiceImpl implements DepreciationService {

    @Autowired
    private DepreciationMapper depreciationMapper;

    @Autowired
    private AssetMapper assetMapper;

    @Autowired
    private CompanyMapper companyMapper;

    /**
     * 定时任务，定期执行折旧，存放到折旧记录表
     * @return
     */
    @Scheduled(cron = "0 0 0 21 * ?", zone = "Asia/Shanghai")
    @Override
    public void updateEveryMonth() {
        //判断状态，调拨，升级改造，封存状态不进行更新
        //判断本月入账，本月不折旧
        //已经折旧完的不折旧


        //获取符合条件的资产
        List<Asset> assets = assetMapper.getDepAsset();

        List<DepreciationDetail> depreciationDetails =new ArrayList<>();

        //资产不为空
        if (assets != null && !assets.isEmpty()){
            for (Asset asset : assets) {
                DepreciationDetail depreciationDetail = insertAsset(asset);
                depreciationDetails.add(depreciationDetail);
            }
        }

        //从折旧记录表里找上次未折旧（系统自动折旧，但是人员没有确认的资产）的资产（比如根据操作人为空的记录）
        List<DepDetail> maxDeps = depreciationMapper.getMaxCumulativeDepreciation();
        List<DepreciationDetail> newDetails = new ArrayList<>();
        for (DepDetail depDetail : maxDeps) {
            newDetails.add(depreciationMapper.getNewDetail(depDetail));
        }

        //可以筛选第一次要折旧的新资产（不做）


        //更新depreciationDetails里的数据,获取本次要折旧的所有资产
        if (depreciationDetails != null && !depreciationDetails.isEmpty()){
            for (DepreciationDetail depreciationDetail : depreciationDetails) {
                for (DepreciationDetail newDetail : newDetails) {
                    //看看资产以前折旧过吗
                    if((newDetail != null &&
                            newDetail.getAssetId() != null &&
                            newDetail.getAssetId().equals(depreciationDetail.getAssetId()))){
                        //以前折旧过，更新数据

                        //将newDetail的属性全部赋值给depreciationDetail
                        depreciationDetail.setAsset(newDetail.getAsset());
                        depreciationDetail.setAssetId(newDetail.getAssetId());
                        depreciationDetail.setOriginalValue(newDetail.getOriginalValue());
                        //depreciationDetail.setNetValueBefore(newDetail.getNetValueBefore());
                        depreciationDetail.setNetValueAfter(newDetail.getNetValueAfter());
                        depreciationDetail.setCurrentDepreciation(newDetail.getCurrentDepreciation());
                        depreciationDetail.setCumulativeDepreciation(newDetail.getCumulativeDepreciation());
                        depreciationDetail.setRemainingValue(newDetail.getRemainingValue());
                        depreciationDetail.setMonthsCumulative(newDetail.getMonthsCumulative());
                        depreciationDetail.setMonthsRemaining(newDetail.getMonthsRemaining());
                        depreciationDetail.setRecordId(newDetail.getRecordId());
                        depreciationDetail.setId(newDetail.getId());

                        //将折旧前净值更新成我们需要的折旧后净值
                        depreciationDetail.setNetValueBefore(newDetail.getNetValueAfter());
                    }
                }
            }
        }else {
            //资产为空,看看记录信息表有没有可以折旧的放进去
            depreciationDetails = newDetails;
        }

        if(depreciationDetails != null && !depreciationDetails.isEmpty()){
            //将资产列表放在工具类里计算折旧
            depreciationDetails = DepreciationUtil.calculationMethod(depreciationDetails);


            //创建一个折旧记录对象
            //DepreciationRecord depreciationRecord = new DepreciationRecord();
            List<DepreciationRecord> depreciationRecords = insertDepreciationDetail(depreciationDetails);

            //将这个折旧记录表的数据插入数据库
            for (DepreciationRecord depreciationRecord : depreciationRecords) {
                if(depreciationRecord.getAssetCount() > 0){
                    depreciationMapper.insertDepreciationRecord(depreciationRecord);
                    //获取最新的记录id
                    Integer id =(depreciationMapper.getMaxId());
                    //将这个折旧详情表插入数据库
                    depreciationMapper.updateDepreciationDetail(depreciationRecord.getDepreciationDetails(), id);
                }

            }
        }else {
            //资产为空，折旧记录表里没有数据,不进行操作
        }
    }


    @Override
    public List<DepreciationRecord> getRecordByCompanyId(Integer companyId) {
        List<DepreciationRecord> depreciationRecords = depreciationMapper.getRecordByCompanyId(companyId);
        return depreciationRecords;
    }

    @Override
    public List<DepreciationRecord> getRecordByCompanyIdSys(Integer companyId) {
        List<DepreciationRecord> depreciationRecords = depreciationMapper.getRecordByCompanyIdSys(companyId);
        return depreciationRecords;
    }

    @Override
    public List<DepreciationDetail> getDetailByRecordId(Integer recordId) {
        List<DepreciationDetail> depreciationDetails = depreciationMapper.getDetailByRecordId(recordId);
        return depreciationDetails;
    }

    @Override
    public void delete(Integer recordId) {
        depreciationMapper.tombstoneRecord(recordId);
    }

    @Override
    public void updateRecord(Integer recordId) {

    }

    //初始化折旧记录对象的属性
    public List<DepreciationRecord> insertDepreciationDetail(List<DepreciationDetail> depreciationDetails){
        List<DepreciationRecord> depreciationRecords = new ArrayList<>();
        //生成月份
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String depreciationMonth = sdf.format(date);



        //根据公司id，生成多个记录表
        depreciationRecords = companyMapper.getRecordList();

        //循环折旧记录表
        for (DepreciationRecord depreciationRecord : depreciationRecords) {
            for (DepreciationDetail depreciationDetail : depreciationDetails) {
                //存放资产对象
                if (depreciationDetail.getAsset().getManagementCompanyId().equals(depreciationRecord.getCompanyId())){
                    depreciationRecord.getDepreciationDetails().add(depreciationDetail);
                }
            }
        }
        for (DepreciationRecord depreciationRecord : depreciationRecords) {
            // 存放折旧记录表月份
            depreciationRecord.setDepreciationMonth(depreciationMonth);

            // 存放资产数量
            Integer assetCount = depreciationRecord.getDepreciationDetails().size();
            depreciationRecord.setAssetCount(assetCount);

            // 存放资产总价
            BigDecimal totalOriginal = depreciationRecord.getDepreciationDetails().stream()
                    .map(detail -> BigDecimal.valueOf(detail.getOriginalValue()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            depreciationRecord.setTotalOriginal(totalOriginal.doubleValue());

            // 存放资产折旧前总净值
            BigDecimal totalNetBefore = depreciationRecord.getDepreciationDetails().stream()
                    .map(detail -> BigDecimal.valueOf(detail.getNetValueBefore()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            depreciationRecord.setTotalNetBefore(totalNetBefore.doubleValue());

            // 存放资产折旧后总净值
            BigDecimal totalNetAfter = depreciationRecord.getDepreciationDetails().stream()
                    .map(detail -> BigDecimal.valueOf(detail.getNetValueAfter()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            depreciationRecord.setTotalNetAfter(totalNetAfter.doubleValue());

            // 存放资产折旧总金额
            BigDecimal totalDepreciation = depreciationRecord.getDepreciationDetails().stream()
                    .map(detail -> BigDecimal.valueOf(detail.getCurrentDepreciation()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            depreciationRecord.setTotalDepreciation(totalDepreciation.doubleValue());
        }

//        for (DepreciationRecord depreciationRecord : depreciationRecords) {
//            //存放折旧记录表月份
//            depreciationRecord.setDepreciationMonth(depreciationMonth);
//            //存放资产数量
//            depreciationRecord.setAssetCount(String.valueOf(depreciationRecord.getDepreciationDetails().size()));
//            //存放资产总价
//            depreciationRecord.setTotalOriginal(depreciationRecord.getDepreciationDetails().stream().mapToDouble(detail -> detail.getOriginalValue()).sum());
//            //存放资产折旧前总净值
//            depreciationRecord.setTotalNetBefore(depreciationRecord.getDepreciationDetails().stream().mapToDouble(detail -> detail.getNetValueBefore()).sum());
//            //存放资产折旧后总净值
//            depreciationRecord.setTotalNetAfter(depreciationRecord.getDepreciationDetails().stream().mapToDouble(detail -> detail.getNetValueAfter()).sum());
//            //存放资产折旧总金额
//            depreciationRecord.setTotalDepreciation(depreciationRecord.getDepreciationDetails().stream().mapToDouble(detail -> detail.getCurrentDepreciation()).sum());
//
//        }

        return depreciationRecords;
    }


    //在折旧详情对象中存放资产对象和对其他属性初始化
    public DepreciationDetail insertAsset(Asset asset) {
        DepreciationDetail depreciationDetail = new DepreciationDetail();
        //存放资产对象
        depreciationDetail.setAsset(asset);
        //明细存放资产id
        depreciationDetail.setAssetId(asset.getId());
        //明细存放原值
        depreciationDetail.setOriginalValue(asset.getOriginalValue());
        //明细存放折旧前净值
        depreciationDetail.setNetValueBefore(asset.getNetValue());
        //存放折旧后净值
        depreciationDetail.setNetValueAfter(0.0);
        //存放本期折旧金额
        depreciationDetail.setCurrentDepreciation(0.0);
        //存放累计折旧金额
        depreciationDetail.setCumulativeDepreciation(asset.getCumulativeDepreciation());
        //存放剩余折旧金额
        depreciationDetail.setRemainingValue(0.0);
        //存放累计折旧期数
        depreciationDetail.setMonthsCumulative(asset.getDepreciationMonths());
        //存放剩余折旧期数
        depreciationDetail.setMonthsRemaining(asset.getRemainingMonths());
        return depreciationDetail;
    }

    @Override
    public void update(DepreciationDetail depreciationDetail) {
        depreciationMapper.update(depreciationDetail);
    }

    //获取资产id返回对应的折旧信息
    public List<DepreciationRecord> getRecordByAssetId(Integer assetId){
        List<DepreciationRecord> depreciationRecords =depreciationMapper.getRecordByAssetId(assetId);
        return depreciationRecords;
    }
}
